package com.wh.wisdomsite.xbox.server.controller.workflow;


import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.plugins.Page;
import com.wh.wisdomsite.xbox.ba.entity.CommonFile;
import com.wh.wisdomsite.xbox.ba.service.ICommonFileService;
import com.wh.wisdomsite.xbox.common.Constants;
import com.wh.wisdomsite.xbox.common.reponse.CommonResult;
import com.wh.wisdomsite.xbox.common.util.ResManager;
import com.wh.wisdomsite.xbox.pojo.st.RuntimeTaskIn;
import com.wh.wisdomsite.xbox.pojo.workflow.TaskFormIn;
import com.wh.wisdomsite.xbox.pojo.workflow.TaskIn;
import com.wh.wisdomsite.xbox.server.util.UserUtils;
import com.wh.wisdomsite.xbox.st.entity.PurchaseApply;
import com.wh.wisdomsite.xbox.st.entity.PurchaseDetail;
import com.wh.wisdomsite.xbox.st.entity.PurchaseFile;
import com.wh.wisdomsite.xbox.st.entity.RuntimeTask;
import com.wh.wisdomsite.xbox.st.service.IPurchaseApplyService;
import com.wh.wisdomsite.xbox.st.service.IPurchaseDetailService;
import com.wh.wisdomsite.xbox.st.service.IPurchaseFileService;
import com.wh.wisdomsite.xbox.st.service.IRuntimeTaskService;
import com.wh.wisdomsite.xbox.us.entity.User;
import com.wh.wisdomsite.xbox.us.service.IEmployeeService;
import com.wh.wisdomsite.xbox.utils.IpUtils;
import com.wh.wisdomsite.xbox.utils.StringUtils;
import com.wh.wisdomsite.xbox.utils.date.DateTool;
import org.activiti.engine.HistoryService;
import org.activiti.engine.RepositoryService;
import org.activiti.engine.RuntimeService;
import org.activiti.engine.TaskService;
import org.activiti.engine.history.HistoricActivityInstance;
import org.activiti.engine.history.HistoricProcessInstance;
import org.activiti.engine.impl.identity.Authentication;
import org.activiti.engine.impl.persistence.entity.ProcessDefinitionEntity;
import org.activiti.engine.impl.pvm.PvmTransition;
import org.activiti.engine.impl.pvm.process.ActivityImpl;
import org.activiti.engine.repository.ProcessDefinition;
import org.activiti.engine.runtime.ProcessInstance;
import org.activiti.engine.task.Comment;
import org.activiti.engine.task.Task;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.json.JSONArray;
import org.json.JSONObject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;


/**
 * 工作流任务管理controller
 * @author 刘旭
 * @version V1.0
 * @Package com.wh.wisdomsite.xbox.server.controller.wo
 * @date 2018年09月21日 9:25
 * @Copyright 企业版权所有
 * @Company 贵州万华科技有限公司Copyright (c) 2018
 */
@Controller
@RequestMapping(value = "/task")
public class TaskController {

    private static final Log logger = LogFactory.getLog(TaskController.class);

    @Resource
    private TaskService taskService;

    @Resource
    private RuntimeService runtimeService;

    @Resource
    private HistoryService historyService;

    @Resource
    private RepositoryService repositoryService;

    @Autowired
    private IPurchaseApplyService iPurchaseApplyService;

    @Autowired
    private IPurchaseDetailService iPurchaseDetailService;

    @Autowired
    private IPurchaseFileService iPurchaseFileService;

    @Autowired
    private ICommonFileService iCommonFileService;

    @Autowired
    private IPurchaseApplyService purchaseApplyService;

    @Autowired
    private IRuntimeTaskService runtimeTaskService;

    @Autowired
    private IEmployeeService iEmployeeService;

    /**
     * 公司管理员标识
     */
    private static final String COMPANYADMINFLAG = "COMPANYADMINFLAG";



    /**
     * 跳转至《我的请购任务列表》
     * @return
     */
    @RequiresPermissions("rules:workflow_task_myTask")
    @RequestMapping(value = "/myTask.do", method = RequestMethod.GET)
    public String myTask() {
        return "workflow/task/myTask";
    }

    /**
     * 我的请购任务列表
     */
    @RequiresPermissions("rules:workflow_task_myTask")
    @RequestMapping(value = "/myTaskList.do", method = RequestMethod.POST)
    public void myTaskList(HttpServletResponse response, RuntimeTaskIn in) {
        JSONArray jsonArray = new JSONArray();
        JSONObject json = new JSONObject();
        try {
            logger.info("我的请购任务列表->>开始");
            User user = UserUtils.getCurrentUser();
            if(in.getPage() == 0) in.setPage(1);
            if(in.getRows() == 0) in.setRows(10);
            Page<RuntimeTask> page = new Page<>();
            page.setCurrent(in.getPage());
            page.setSize(in.getRows());
            //设置查询条件
            RuntimeTask runtimeTask = new RuntimeTask();
            //设置办理人,不是超级管理员
            String compCode = null;
            if(!UserUtils.isSysAdmin()){
                //不是公司管理员
                if(!UserUtils.isCompAdmin()){
                    runtimeTask.setAssignee(user.getLoginName());
                }else{
                    compCode = UserUtils.getCurrentUser().getCompany().getCompCode();
                }
            }
            Page<RuntimeTask> pages = runtimeTaskService.queryPage(page, runtimeTask, compCode);
            if(pages.getRecords().size() > 0){
                for(RuntimeTask task : pages.getRecords()){
                    JSONObject object = new JSONObject(task);
                    object.put("create_time", DateTool.format(task.getCreate_time(), "yyyy-MM-dd HH:mm:ss"));
                    jsonArray.put(object);
                }
            }
            json.put("total",  pages.getTotal());
            json.put("rows", jsonArray);
            ResManager.getTextOut(response).print(json);
            logger.info("我的请购任务列表->>结束");
        } catch (Exception e){
            e.printStackTrace();
            logger.error("我的请购任务列表->Exception " + e.getMessage());
        }
    }





    /**
     * 调整至办理任务表单页面
     * @return
     */
    @RequiresPermissions("rules:workflow_task_edit")
    @RequestMapping(value = "/toTaskForm.do", method = RequestMethod.GET)
    public String toTaskForm(TaskIn in, HttpServletRequest request) {
        try {
            logger.info("跳转至查看采购->>toTaskForm->>开始");
            //1. 根据任务编号获取对Task对象
            Task task = taskService.createTaskQuery().taskId(in.getId()).singleResult();
            //2. 根据任务对象获取流程实例, 在根据流程实例获取流ProcessInstance对象
            ProcessInstance pi = runtimeService.createProcessInstanceQuery().processInstanceId(task.getProcessInstanceId()).singleResult();
            //3. 通过流程实例对象获取BUSINESS_KEY
            String buninessKey = pi.getBusinessKey();
            //4：获取BUSINESS_KEY对应的主键ID，使用主键ID，查询请假单对象（LeaveBill.1）
            String purId = "";
            if(StringUtils.isNotBlank(buninessKey)){
                //截取字符串，取buniness_key小数点的第2个值
                purId = buninessKey.split("\\.")[1];
            }

            //获取请购对象
            PurchaseApply purchaseApply = iPurchaseApplyService.getPurchaseApplyByPurId(purId);
            //获取请购详情
            EntityWrapper<PurchaseDetail> ewPurchaseDetail = new EntityWrapper<>();
            ewPurchaseDetail.eq("purd.purId", purId);
            List<PurchaseDetail> purchaseDetails = iPurchaseDetailService.getPurchaseDetails(ewPurchaseDetail);
            //获取请购相关附件
            List<CommonFile> commonFiles = new ArrayList<>();
            EntityWrapper<PurchaseFile> ewPurchaseFile = new EntityWrapper<>();
            ewPurchaseFile.eq("purId", purId);
            List<PurchaseFile> purchaseFiles = iPurchaseFileService.selectList(ewPurchaseFile);
            if(null != purchaseFiles && purchaseFiles.size() > 0){
                List<String> fileIds = new ArrayList<>();
                for(PurchaseFile purchaseFile : purchaseFiles){
                    fileIds.add(purchaseFile.getFileId());
                }
                commonFiles = iCommonFileService.selectBatchIds(fileIds);
            }

            //二：已知任务ID，查询ProcessDefinitionEntiy对象，从而获取当前任务完成之后的连线名称，并放置到List<String>集合中
            List<String> outcomeList = this.findOutComeListByTaskId(in.getId());

            //4. 根据业务编号查询历史流程实例
            String key = purchaseApply.getClass().getSimpleName();
            String businessKey = key + "." + purId;
            HistoricProcessInstance historicProcessInstance = historyService.createHistoricProcessInstanceQuery().processInstanceBusinessKey(businessKey).singleResult();
            //5. 获取所有活动节点历史表（条件： 流程实例编号）
            List<HistoricActivityInstance> historicActivityInstances = historyService.createHistoricActivityInstanceQuery().processInstanceId(historicProcessInstance.getId()).orderByHistoricActivityInstanceStartTime().asc().list();
            Integer compId = UserUtils.getCurrentUser().getCompanyId();
            Map<String, String> empNames = iEmployeeService.getEmpNamesByCompId(String.valueOf(compId));

            //6. 获取批准列表信息
            List<Comment> comments = taskService.getProcessInstanceComments(historicProcessInstance.getId());

            request.setAttribute("historicActivityInstances", historicActivityInstances);
            request.setAttribute("purchaseApply", purchaseApply);
            request.setAttribute("purchaseDetails", purchaseDetails);
            request.setAttribute("commonFiles", commonFiles);
            request.setAttribute("thisButns", outcomeList);
            request.setAttribute("task", task);
            request.setAttribute("comments", comments);
            request.setAttribute("emNameMap", empNames);
            logger.info("跳转至查看采购->>toTaskForm->>结束");
        } catch (Exception e){
            e.printStackTrace();
            logger.error("跳转至查看采购->>toTaskForm->>Exception " + e.getMessage());
        }
            return "workflow/task/myTaskForm";
    }






    /**
     * 提交任务
     * @return
     */
    @RequiresPermissions("rules:workflow_task_edit")
    @RequestMapping(value = "/saveTaskForm.do", method = RequestMethod.POST)
    public void saveTaskForm(TaskFormIn in, HttpServletResponse response, HttpServletRequest request) {
        CommonResult result = new CommonResult();
        String repsonsText = "";
        try {
            logger.info("提交任务->>saveTaskForm->>开始");
            String taskId = in.getTaskId();
            String purId = in.getPurId();
            String assignee = in.getAssignee();
            String message = in.getMessage();
            Integer radioKey = in.getRadioKey();

            //1. 获取当前任务
            Task task = taskService.createTaskQuery().taskId(taskId).singleResult();
            String processInstanceId = task.getProcessInstanceId();

            //2. 添加批注
            String messageKey = (1 == radioKey) ? "同意▲" : "不同意▲";
            Authentication.setAuthenticatedUserId(UserUtils.getCurrentUser().getLoginName());
            taskService.addComment(taskId, processInstanceId, messageKey +  message);

            //3. 设置流程业务变量
            Map<String, Object> variables = new HashMap<>();
            if(1 == radioKey){
                variables.put("outcome", "同意");
                //更新采购状态: 1审核中
                //更新上报状态: 2已上报
                PurchaseApply purchaseApply = new PurchaseApply();
                purchaseApply.setPurId(purId);
                purchaseApply.setCheckState("1");
                purchaseApply.setReportState("2");
                purchaseApplyService.updateById(purchaseApply);
                if(StringUtils.isNotEmpty(in.getVariableName())){
                    //设置下一步办理人
                    variables.put(in.getVariableName(), assignee);
               }
            }
            //不同意(驳回)
            if(2 == radioKey){
                variables.put("outcome", "驳回");
                //更新采购状态3: 已驳回, 且上报状态为1: 未上报
                PurchaseApply purchaseApply = new PurchaseApply();
                purchaseApply.setPurId(purId);
                purchaseApply.setReportState("1");
                purchaseApply.setCheckState("3");
                purchaseApplyService.updateById(purchaseApply);
                //判断发起人就不同意
                if("departmentMgr".equalsIgnoreCase(in.getVariableName())){
                    result.setCode(Constants.CODE_SUCCESS);
                    result.setMessage("办理任务完成");
                    //向浏览器输出
                    output(request, response, repsonsText, result);
                    return;
                }
            }
            //4. 完成任务
            taskService.complete(task.getId(), variables);

            //5. 在完成任务之后，判断流程是否结束
            ProcessInstance processInstance = runtimeService.createProcessInstanceQuery().processInstanceId(processInstanceId).singleResult();
            //判断流程是否结束
            if(null == processInstance){
                //1. 更新采购单状态
                PurchaseApply purchaseApply = new PurchaseApply();
                purchaseApply.setPurId(purId);
                purchaseApply.setCheckState("2");
                purchaseApplyService.updateById(purchaseApply);
                //2. 更新已请购数量
                purchaseApplyService.checkPurchaseApply(purId);
            }

            result.setCode(Constants.CODE_SUCCESS);
            result.setMessage("办理任务完成");
            //向浏览器输出
            output(request, response, repsonsText, result);
            logger.info("提交任务->>saveTaskForm->>结束");
        } catch (Exception e){
            e.printStackTrace();
            result.setCode(Constants.CODE_FAIL);
            result.setMessage("办理任务完成");
            logger.error("提交任务->>saveTaskForm->>Exception " + e.getMessage());
        }

    }


    /**
     * 向浏览器输出
     * @param request
     * @param response
     * @param repsonsText
     * @param result
     */
    public void output(HttpServletRequest request, HttpServletResponse response, String repsonsText, CommonResult result){
        if(IpUtils.isIE(request)){
            repsonsText = "{code: '" + result.getCode()  + "', message: '" + result.getMessage() + "', result: {} }";
            ResManager.getTextOut(response).print(repsonsText);
        }else {
            ResManager.getJsonOut(response).print(CommonResult.getJsonObject(result));
        }
    }





    /**
     * 跳转至部署流程定义
     * @return
     */
    @RequiresPermissions("rules:workflow_task_view")
    @RequestMapping("/viewCurrentImage")
    public String viewCurrentImage(HttpServletRequest request, TaskFormIn in){
        //1. 通过任务Id获取任务对象
        Task task = taskService.createTaskQuery().taskId(in.getTaskId()).singleResult();
        //2. 通过流程定义Id获取流程定义对象
        ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery().processDefinitionId(task.getProcessDefinitionId()).singleResult();

        //3. 存放坐标
        Map<String, Object> map = new HashMap<>();
        //获取流程定义的实体对象（对应.bpmn文件中的数据）
        ProcessDefinitionEntity processDefinitionEntity = (ProcessDefinitionEntity) repositoryService.getProcessDefinition(task.getProcessDefinitionId());
        //流程实例ID
        String processInstanceId = task.getProcessInstanceId();
        //使用流程实例ID，查询正在执行的执行对象表，获取当前活动对应的流程实例对象
        ProcessInstance pi = runtimeService.createProcessInstanceQuery().processInstanceId(processInstanceId).singleResult();
        //获取当前活动的ID
        String activityId = pi.getActivityId();
        //获取当前活动对象
        ActivityImpl activityImpl = processDefinitionEntity.findActivity(activityId);//活动ID
        //获取坐标
        map.put("x", activityImpl.getX());
        map.put("y", activityImpl.getY());
        map.put("width", activityImpl.getWidth());
        map.put("height", activityImpl.getHeight());

        request.setAttribute("deploymentId", processDefinition.getDeploymentId());
        request.setAttribute("diagramResourceName", processDefinition.getDiagramResourceName());
        request.setAttribute("acs", map);
        return "workflow/task/currentView";
    }











    /**
     *
     * @param taskId
     * @return
     */
    public List<String>  findOutComeListByTaskId(String taskId){
        //返回存放连线的名称集合
        List<String> list = new ArrayList<>();
        //1:使用任务ID，查询任务对象
        Task task = taskService.createTaskQuery().taskId(taskId).singleResult();
        //2：获取流程定义ID
        String processDefinitionId = task.getProcessDefinitionId();
        //3：查询ProcessDefinitionEntiy对象
        ProcessDefinitionEntity processDefinitionEntity = (ProcessDefinitionEntity) repositoryService.getProcessDefinition(processDefinitionId);
        //使用任务对象Task获取流程实例ID
        String processInstanceId = task.getProcessInstanceId();
        //使用流程实例ID，查询正在执行的执行对象表，返回流程实例对象
        ProcessInstance pi = runtimeService.createProcessInstanceQuery().processInstanceId(processInstanceId).singleResult();
        //获取当前活动的id
        String activityId = pi.getActivityId();
        //4：获取当前的活动
        ActivityImpl activityImpl = processDefinitionEntity.findActivity(activityId);
        //5：获取当前活动完成之后连线的名称
        List<PvmTransition> pvmList = activityImpl.getOutgoingTransitions();
        if(pvmList!=null && pvmList.size()>0){
            for(PvmTransition pvm:pvmList){
                String name = (String) pvm.getProperty("name");
                if(StringUtils.isNotBlank(name) && !"驳回".equalsIgnoreCase(name)){
                    list.add(name);
                } else{
                    list.add("提交");
                }
            }
        }
        return list;
    }
}
